package 狂神多线程;
//管程法
// 测试:生产者消费者模型-->利用缓冲区解决:管程法
// 生产者 消费者 产品 缓冲区
public class TestPC {
    public static void main(String[] args) {
        SysContainer sysContainer = new SysContainer();
        new Producer(sysContainer).start();
        new Consumer(sysContainer).start();
    }
}

// 产品
class Chicken {
    int id;
    public Chicken(int id) {
        this.id = id;
    }
}

// 缓冲区
class SysContainer {
    Chicken[] chickens = new Chicken[10]; // 缓冲区大小为10
    int count = 0; // 产品计数器

    // 生产者放入产品（同步方法，保证线程安全）
    public synchronized void push(Chicken chicken) {
        // 缓冲区满时，生产者等待
        if (count == chickens.length) {
            try {
                this.wait(); // 释放锁，进入等待队列
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        // 放入产品
        chickens[count] = chicken;
        count++;
        this.notify(); // 通知消费者可消费
    }

    // 消费者取出产品（同步方法，保证线程安全）
    public synchronized Chicken pop() {
        // 缓冲区空时，消费者等待
        if (count == 0) {
            try {
                this.wait(); // 释放锁，进入等待队列
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        // 取出产品（先减计数器再取值，避免索引越界）
        count--;
        Chicken chicken = chickens[count];
        this.notify(); // 通知生产者可生产
        return chicken;
    }
}

// 生产者
class Producer extends Thread {
    SysContainer container;
    public Producer(SysContainer container) {
        this.container = container;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("生产了: " + i + " 只鸡");
            container.push(new Chicken(i));
            try {
                Thread.sleep(500); // 模拟生产耗时，可根据需要调整
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

// 消费者
class Consumer extends Thread {
    SysContainer container;
    public Consumer(SysContainer container) {
        this.container = container;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("消费了--> " + container.pop().id + " 只鸡");
            try {
                Thread.sleep(800); // 模拟消费耗时，可根据需要调整
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}